// #include <unistd.h>
// #include <stdlib.h>
// #include <stdio.h>
// #include <string.h>
// #include <pthread.h>
// void *rout(void *arg)
// {
//     int i;
//     for (;;)
//     {
//         printf("I'am thread 1\n");
//         sleep(1);
//     }
// }
// int main(void)
// {
//     pthread_t tid;
//     int ret;
//     if ((ret = pthread_create(&tid, NULL, rout, NULL)) != 0)
//     {
//         fprintf(stderr, "pthread_create : %s\n", strerror(ret));
//         exit(EXIT_FAILURE);
//     }
//     int i;
//     for (;;)
//     {
//         printf("I'am main thread\n");
//         sleep(1);
//     }
// }

// #include <stdio.h>
// #include <stdlib.h>
// #include <string.h>
// #include <unistd.h>
// #include <pthread.h>
// void *thread1(void *arg)
// {
//     printf("thread 1 returning ... \n");
//     int *p = (int *)malloc(sizeof(int));
//     *p = 1;
//     return (void *)p;
// }
// void *thread2(void *arg)
// {
//     printf("thread 2 exiting ...\n");
//     int *p = (int *)malloc(sizeof(int));
//     *p = 2;
//     pthread_exit((void *)p);
// }
// void *thread3(void *arg)
// {
//     while (1)
//     { //
//         printf("thread 3 is running ...\n");
//         sleep(1);
//     }
//     return NULL;
// }
// int main(void)
// {
//     pthread_t tid;
//     void *ret;
//     // thread 1 return
//     pthread_create(&tid, NULL, thread1, NULL);
//     pthread_join(tid, &ret);
//     printf("thread return, thread id %X, return code:%d\n", tid, *(int *)ret);
//     free(ret);
//     // thread 2 exit
//     pthread_create(&tid, NULL, thread2, NULL);
//     pthread_join(tid, &ret);
//     printf("thread return, thread id %X, return code:%d\n", tid, *(int *)ret);
//     free(ret);
//     // thread 3 cancel by other
//     pthread_create(&tid, NULL, thread3, NULL);
//     sleep(3);
//     pthread_cancel(tid);
//     pthread_join(tid, &ret);
//     if (ret == PTHREAD_CANCELED)
//         printf("thread return, thread id %X, return code:PTHREAD_CANCELED\n", tid);
//     else
//         printf("thread return, thread id %X, return code:NULL\n", tid);
// }

// #include <stdio.h>
// #include <stdlib.h>
// #include <string.h>
// #include <unistd.h>
// #include <pthread.h>
// void *thread_run(void *arg)
// {
//     pthread_detach(pthread_self());
//     printf("%s\n", (char *)arg);
//     return NULL;
// }
// int main(void)
// {
//     pthread_t tid;
//     if (pthread_create(&tid, NULL, thread_run, "thread1 run...") != 0)
//     {
//         printf("create thread error\n");
//         return 1;
//     }
//     int ret = 0;
//     sleep(1); // 很重要，要让线程先分离，再等待
//     if (pthread_join(tid, NULL) == 0)
//     {
//         printf("pthread wait success\n");
//         ret = 0;
//     }
//     else
//     {
//         printf("pthread wait failed\n");
//         ret = 1;
//     }
//     return ret;
// }

// // 操作共享变量会有问题的售票系统代码
// #include <stdio.h>
// #include <stdlib.h>
// #include <string.h>
// #include <unistd.h>
// #include <pthread.h>
// int ticket = 100;
// void *route(void *arg)
// {
//     char *id = (char *)arg;
//     while (1)
//     {
//         if (ticket > 0)
//         {
//             usleep(1000);
//             printf("%s sells ticket:%d\n", id, ticket);
//             ticket--;
//         }
//         else
//         {
//             break;
//         }
//     }
// }
// int main(void)
// {
//     pthread_t t1, t2, t3, t4;
//     pthread_create(&t1, NULL, route, "thread 1");
//     pthread_create(&t2, NULL, route, "thread 2");
//     pthread_create(&t3, NULL, route, "thread 3");
//     pthread_create(&t4, NULL, route, "thread 4");
//     pthread_join(t1, NULL);
//     pthread_join(t2, NULL);
//     pthread_join(t3, NULL);
//     pthread_join(t4, NULL);
// }

// #include <stdio.h>
// #include <stdlib.h>
// #include <string.h>
// #include <unistd.h>
// #include <pthread.h>
// #include <sched.h>
// int ticket = 100;
// pthread_mutex_t mutex;
// void *route(void *arg)
// {
//     char *id = (char *)arg;
//     while (1)
//     {
//         pthread_mutex_lock(&mutex);
//         if (ticket > 0)
//         {
//             usleep(1000);
//             printf("%s sells ticket:%d\n", id, ticket);
//             ticket--;
//             pthread_mutex_unlock(&mutex);
//             // sched_yield(); 放弃CPU
//         }
//         else
//         {
//             pthread_mutex_unlock(&mutex);
//             break;
//         }
//     }
// }
// int main(void)
// {
//     pthread_t t1, t2, t3, t4;
//     pthread_mutex_init(&mutex, NULL);
//     pthread_create(&t1, NULL, route, "thread 1");
//     pthread_create(&t2, NULL, route, "thread 2");
//     pthread_create(&t3, NULL, route, "thread 3");
//     pthread_create(&t4, NULL, route, "thread 4");
//     pthread_join(t1, NULL);
//     pthread_join(t2, NULL);
//     pthread_join(t3, NULL);
//     pthread_join(t4, NULL);
//     pthread_mutex_destroy(&mutex);
// }

// #include <stdio.h>
// #include <stdlib.h>
// #include <string.h>
// #include <unistd.h>
// #include <pthread.h>
// pthread_cond_t cond;
// pthread_mutex_t mutex;
// void *r1(void *arg)
// {
//     while (1)
//     {
//         pthread_cond_wait(&cond, &mutex);
//         printf("活动\n");
//     }
// }
// void *r2(void *arg)
// {
//     while (1)
//     {
//         pthread_cond_signal(&cond);
//         sleep(1);
//     }
// }
// int main(void)
// {
//     pthread_t t1, t2;
//     pthread_cond_init(&cond, NULL);
//     pthread_mutex_init(&mutex, NULL);
//     pthread_create(&t1, NULL, r1, NULL);
//     pthread_create(&t2, NULL, r2, NULL);
//     pthread_join(t1, NULL);
//     pthread_join(t2, NULL);
//     pthread_mutex_destroy(&mutex);
//     pthread_cond_destroy(&cond);
// }

// #include <iostream>
// #include <queue>
// #include <stdlib.h>
// #include <pthread.h>
// #define NUM 8
// class BlockQueue
// {
// private:
//     std::queue<int> q;
//     int cap;
//     pthread_mutex_t lock;
//     pthread_cond_t full;
//     pthread_cond_t empty;
// private:
//     void LockQueue()
//     {
//         pthread_mutex_lock(&lock);
//     }
//     void UnLockQueue()
//     {
//         pthread_mutex_unlock(&lock);
//     }
//     void ProductWait()
//     {
//         pthread_cond_wait(&full, &lock);
//     }
//     void ConsumeWait()
//     {
//         pthread_cond_wait(&empty, &lock);
//     }
//     void NotifyProduct()
//     {
//         pthread_cond_signal(&full);
//     }
//     void NotifyConsume()
//     {
//         pthread_cond_signal(&empty);
//     }
//     bool IsEmpty()
//     {
//         return (q.size() == 0 ? true : false);
//     }
//     bool IsFull()
//     {
//         return (q.size() == cap ? true : false);
//     }
// public:
//     BlockQueue(int _cap = NUM) : cap(_cap)
//     {
//         pthread_mutex_init(&lock, NULL);
//         pthread_cond_init(&full, NULL);
//         pthread_cond_init(&empty, NULL);
//     }
//     void PushData(const int &data)
//     {
//         LockQueue();
//         while (IsFull())
//         {
//             NotifyConsume();
//             std::cout << "queue full, notify consume data, product stop." << std::endl;
//             ProductWait();
//         }
//         q.push(data);
//         // NotifyConsume();
//         UnLockQueue();
//     }
//     void PopData(int &data)
//     {
//         LockQueue();
//         while (IsEmpty())
//         {
//             NotifyProduct();
//             std::cout << "queue empty, notify product data, consume stop." << std::endl;
//             ConsumeWait();
//         }
//         data = q.front();
//         q.pop();
//         // NotifyProduct();
//         UnLockQueue();
//     }
//     ~BlockQueue()
//     {
//         pthread_mutex_destroy(&lock);
//         pthread_cond_destroy(&full);
//         pthread_cond_destroy(&empty);
//     }
// };
// void *consumer(void *arg)
// {
//     BlockQueue *bqp = (BlockQueue *)arg;
//     int data;
//     for (;;)
//     {
//         bqp->PopData(data);
//         std::cout << "Consume data done : " << data << std::endl;
//     }
// }
// // more faster
// void *producter(void *arg)
// {
//     BlockQueue *bqp = (BlockQueue *)arg;
//     srand((unsigned long)time(NULL));
//     for (;;)
//     {
//         int data = rand() % 1024;
//         bqp->PushData(data);
//         std::cout << "Prodoct data done: " << data << std::endl;
//         // sleep(1);
//     }
// }
// int main()
// {
//     BlockQueue bq;
//     pthread_t c, p;
//     pthread_create(&c, NULL, consumer, (void *)&bq);
//     pthread_create(&p, NULL, producter, (void *)&bq);
//     pthread_join(c, NULL);
//     pthread_join(p, NULL);
//     return 0;
// }

// #include <iostream>
// #include <vector>
// #include <stdlib.h>
// #include <semaphore.h>
// #include <pthread.h>
// #include <unistd.h>
// #define NUM 16
// class RingQueue
// {
// private:
//     std::vector<int> q;
//     int cap;
//     sem_t data_sem;
//     sem_t space_sem;
//     int consume_step;
//     int product_step;
// public:
//     RingQueue(int _cap = NUM) : q(_cap), cap(_cap)
//     {
//         sem_init(&data_sem, 0, 0);
//         sem_init(&space_sem, 0, cap);
//         consume_step = 0;
//         product_step = 0;
//     }
//     void PutData(const int &data)
//     {
//         sem_wait(&space_sem); // P
//         q[consume_step] = data;
//         consume_step++;
//         consume_step %= cap;
//         sem_post(&data_sem); // V
//     }
//     void GetData(int &data)
//     {
//         sem_wait(&data_sem);
//         data = q[product_step];
//         product_step++;
//         product_step %= cap;
//         sem_post(&space_sem);
//     }
//     ~RingQueue()
//     {
//         sem_destroy(&data_sem);
//         sem_destroy(&space_sem);
//     }
// };
// void *consumer(void *arg)
// {
//     RingQueue *rqp = (RingQueue *)arg;
//     int data;
//     for (;;)
//     {
//         rqp->GetData(data);
//         std::cout << "Consume data done : " << data << std::endl;
//         sleep(1);
//     }
// }
// // more faster
// void *producter(void *arg)
// {
//     RingQueue *rqp = (RingQueue *)arg;
//     srand((unsigned long)time(NULL));
//     for (;;)
//     {
//         int data = rand() % 1024;
//         rqp->PutData(data);
//         std::cout << "Prodoct data done: " << data << std::endl;
//         // sleep(1);
//     }
// }
// int main()
// {
//     RingQueue rq;
//     pthread_t c, p;
//     pthread_create(&c, NULL, consumer, (void *)&rq);
//     pthread_create(&p, NULL, producter, (void *)&rq);
//     pthread_join(c, NULL);
//     pthread_join(p, NULL);
// }

// #include <vector>
// #include <sstream>
// #include <cstdio>
// #include <cstdlib>
// #include <cstring>
// #include <unistd.h>
// #include <pthread.h>
// volatile int ticket = 1000;
// pthread_rwlock_t rwlock;
// void *reader(void *arg)
// {
//     char *id = (char *)arg;
//     while (1)
//     {
//         pthread_rwlock_rdlock(&rwlock);
//         if (ticket <= 0)
//         {
//             pthread_rwlock_unlock(&rwlock);
//             break;
//         }
//         printf("%s: %d\n", id, ticket);
//         pthread_rwlock_unlock(&rwlock);
//         usleep(1);
//     }
//     return nullptr;
// }
// void *writer(void *arg)
// {
//     char *id = (char *)arg;
//     while (1)
//     {
//         pthread_rwlock_wrlock(&rwlock);
//         if (ticket <= 0)
//         {
//             pthread_rwlock_unlock(&rwlock);
//             break;
//         }
//         printf("%s: %d\n", id, --ticket);
//         pthread_rwlock_unlock(&rwlock);
//         usleep(1);
//     }
//     return nullptr;
// }
// struct ThreadAttr
// {
//     pthread_t tid;
//     std::string id;
// };
// std::string create_reader_id(std::size_t i)
// {
//     // 利用 ostringstream 进行 string 拼接
//     std::ostringstream oss("thread reader ", std::ios_base::ate);
//     oss << i;
//     return oss.str();
// }
// std::string create_writer_id(std::size_t i)
// {
//     // 利用 ostringstream 进行 string 拼接
//     std::ostringstream oss("thread writer ", std::ios_base::ate);
//     oss << i;
//     return oss.str();
// }
// void init_readers(std::vector<ThreadAttr> &vec)
// {
//     for (std::size_t i = 0; i < vec.size(); ++i)
//     {
//         vec[i].id = create_reader_id(i);
//         pthread_create(&vec[i].tid, nullptr, reader, (void *)vec[i].id.c_str());
//     }
// }
// void init_writers(std::vector<ThreadAttr> &vec)
// {
//     for (std::size_t i = 0; i < vec.size(); ++i)
//     {
//         vec[i].id = create_writer_id(i);
//         pthread_create(&vec[i].tid, nullptr, writer, (void *)vec[i].id.c_str());
//     }
// }
// void join_threads(std::vector<ThreadAttr> const &vec)
// {
//     // 我们按创建的 逆序 来进行线程的回收
//     for (std::vector<ThreadAttr>::const_reverse_iterator it = vec.rbegin(); it !=
//                                                                             vec.rend();
//          ++it)
//     {
//         pthread_t const &tid = it->tid;
//         pthread_join(tid, nullptr);
//     }
// }
// void init_rwlock()
// {
// #if 0 // 写优先
// pthread_rwlockattr_t attr;
// pthread_rwlockattr_init(&attr);
// pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
// pthread_rwlock_init(&rwlock, &attr);
// pthread_rwlockattr_destroy(&attr);
// #else // 读优先，会造成写饥饿
//     pthread_rwlock_init(&rwlock, nullptr);
// #endif
// }
// int main()
// {
//     // 测试效果不明显的情况下，可以加大 reader_nr
//     // 但也不能太大，超过一定阈值后系统就调度不了主线程了
//     const std::size_t reader_nr = 1000;
//     const std::size_t writer_nr = 2;
//     std::vector<ThreadAttr> readers(reader_nr);
//     std::vector<ThreadAttr> writers(writer_nr);
//     init_rwlock();
//     init_readers(readers);
//     init_writers(writers);
//     join_threads(writers);
//     join_threads(readers);
//     pthread_rwlock_destroy(&rwlock);
// }

// #include <stdio.h>  
// #include <stdlib.h>  
// #include <signal.h>  
// #include <unistd.h> 
// // 自定义的信号处理函数  
// void sigint_handler(int sig_num) {  
//     printf("捕获到 SIGINT 信号，信号编号：%d\n", sig_num);  
//     // 这里可以添加清理代码或执行其他任务  
//     // 注意：不要在信号处理函数中调用非异步信号安全的函数  
//     // 退出程序，或者你可以决定不退出  
//     exit(0);  
// }  
// int main() {  
//     struct sigaction act;  
//     // 初始化 sigaction 结构体  
//     act.sa_handler = sigint_handler; // 设置信号处理函数  
//     sigemptyset(&act.sa_mask);       // 初始化信号屏蔽字  
//     act.sa_flags = 0;                // 初始化行为标志  
//     // 使用 sigaction 安装 SIGINT 的处理函数  
//     if (sigaction(SIGINT, &act, NULL) == -1) {  
//         perror("sigaction");  
//         exit(1);  
//     }  
//     // 模拟一个长时间运行的任务  
//     while (1) {  
//         printf("程序正在运行...\n");  
//         sleep(1); // 暂停一秒  
//     }  
//     return 0;  
// }

#include <stdio.h>  
#include <stdlib.h>  
#include <signal.h>  
#include <unistd.h>  
  
int main() {  
    sigset_t set;  
  
    // 初始化信号集，清空所有信号  
    sigemptyset(&set);  
  
    // 向信号集中添加想要阻塞的信号  
    sigaddset(&set, SIGINT); // 2号信号  
    sigaddset(&set, 40);     // 40号信号，注意确保这个信号在你的系统上是有效的  
  
    // 阻塞这些信号  
    if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {  
        perror("sigprocmask");  
        exit(EXIT_FAILURE);  
    }  
  
    // 在这里执行一些操作，这些操作不会被2号和40号信号中断  
    printf("2号和40号信号现在被阻塞。\n");  
    sleep(10); // 假设这里有一些需要长时间运行的操作  
  
    // 你可以在这里解除对信号的阻塞（如果需要的话）  
    // 使用 sigprocmask(SIG_UNBLOCK, &set, NULL);  
  
    printf("如果程序继续运行到这里，说明没有接收到被阻塞的信号。\n");  
  
    return 0;  
}